package com.jier.controller.console;

import com.jier.annotation.ValidateField;
import com.jier.annotation.ValidateGroup;
import com.jier.common.Result;
import com.jier.common.exception.HttpParamException;
import com.jier.common.permission.Permission;
import com.jier.common.util.MD5Util;
import com.jier.common.util.RegularUtil;
import com.jier.common.util.StringUtil;
import com.jier.controller.BaseController;
import com.jier.dto.SystemUserParamDto;
import com.jier.entities.SystemUser;
import com.jier.entities.SystemUserRole;
import com.jier.model.PageParam;
import com.jier.service.ISystemUserRoleService;
import com.jier.service.ISystemUserService;
import com.jier.vo.admin.SystemUserVo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.jier.common.util.MD5Util.string2MD5;

/**
 * 系统用户控制器
 *
 * @author jie_r
 * @date 2018/03/08
 */
@RestController
@RequestMapping("/console/systemUsers")
public class SystemUserController extends BaseController {
    @Autowired
    private ISystemUserService systemUserService;

    @Autowired
    private ISystemUserRoleService systemUserRoleService;

    /**
     * 登陆
     *
     * @param account
     * @param password
     * @param session
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST, produces = "application/json;")
    public ModelAndView login(@RequestParam("account") String account, @RequestParam("password") String password, HttpSession session) throws Exception {
        ModelAndView mv = new ModelAndView();
        SystemUser systemUser = systemUserService.login(account, password);
        String viewName = PROJECT_ADMIN_LOGIN;
        if (systemUser != null) {
            viewName = PROJECT_ADMIN_INDEX;
            session.setAttribute("currentUser", systemUser);
        } else {
            mv.addObject("message", "账户不存在或密码不正确");
        }
        mv.setViewName("redirect:" + viewName);
        return mv;
    }

    /**
     * 系统用户首页-管理页面
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/index.html", method = RequestMethod.GET)
    @ApiOperation(value = "系统用户首页-管理页面", hidden = true, httpMethod = "GET")
    @Permission(code = "010101", content = "系统用户首页-管理页面")
    public ModelAndView index() throws Exception {
        return new ModelAndView("/systemUser/systemUsers");
    }

    /**
     * 添加系统用户-管理页面
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/add.html", method = RequestMethod.GET)
    @ApiOperation(value = "添加系统用户-管理页面", hidden = true, httpMethod = "GET")
    @Permission(code = "010102", content = "添加系统用户-管理页面")
    public ModelAndView addPage() throws Exception {
        return new ModelAndView("/systemUser/add_systemUser");
    }

    /**
     * 编辑系统用户-管理页面
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/edit.html", method = RequestMethod.GET)
    @ApiOperation(value = "编辑系统用户-管理页面", hidden = true, httpMethod = "GET")
    @Permission(code = "010103", content = "编辑系统用户-管理页面")
    public ModelAndView editPage(Integer id) throws Exception {
        ModelAndView mv = new ModelAndView("/systemUser/edit_systemUser");
        SystemUser systemUser = systemUserService.getById(id);
        mv.addObject("systemUser", systemUser);
        return mv;
    }

    /**
     * 分配角色-管理页面
     *
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/assignRole.html", method = RequestMethod.GET)
    @ApiOperation(value = "分配角色-管理页面", hidden = true, httpMethod = "GET")
    @Permission(code = "010103", content = "分配角色-管理页面")
    public ModelAndView assignRolePage(Integer id) throws Exception {
        ModelAndView mv = new ModelAndView("/systemUser/assign_role");
        SystemUserRole systemUserRole = systemUserRoleService.getById(id);
        mv.addObject("systemUserRole", systemUserRole);
        mv.addObject("id", id);
        return mv;
    }

    /**
     * 修改密码-管理页面
     *
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/editPassword.html", method = RequestMethod.GET)
    @ApiOperation(value = "修改密码-管理页面", hidden = true, httpMethod = "GET")
    @Permission(code = "010103", content = "修改密码-管理页面")
    public ModelAndView editPasswordPage(Integer id) throws Exception {
        return new ModelAndView("/systemUser/edit_password");
    }

    /**
     * 获取系统用户
     *
     * @param pageParam
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json;")
    @ApiOperation(value = "获取系统用户", httpMethod = "GET", produces = "application/json;")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "keyword", value = "关键字检索，范围：编号/名字/联系方式", dataType = "String"),
            @ApiImplicitParam(name = "status", value = "状态", dataType = "String"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String")
    })
    @Permission(code = "010101", content = "获取系统用户")
    public ResponseEntity<Result<SystemUserVo>> getSystemUsers(
            String keyword, Integer status,
            String startDate, String endDate, PageParam pageParam) throws Exception {
        SystemUserParamDto param = new SystemUserParamDto();
        param.setKeyword(keyword);
        param.setStatus(status);
        param.setStartDate(StringUtil.isEmpty(startDate) ? startDate : startDate + " 00:00:00");
        param.setEndDate(StringUtil.isEmpty(endDate) ? endDate : endDate + " 23:59:59");
        Result<SystemUser> result = systemUserService.getSystemUsers(param, getPage(pageParam));
        List<SystemUserVo> systemUserVoList = result.getContent().stream().map(SystemUserVo::new).collect(Collectors.toList());
        return ok(new Result(result.getPage(), systemUserVoList));
    }

    /**
     * 添加系统用户
     *
     * @param name
     * @param phone
     * @param status
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json;")
    @ApiOperation(value = "添加系统用户", httpMethod = "POST", produces = "application/json;")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "编号", dataType = "String", required = true),
            @ApiImplicitParam(name = "name", value = "名字", dataType = "String", required = true),
            @ApiImplicitParam(name = "phone", value = "联系方式", dataType = "String", required = true),
            @ApiImplicitParam(name = "status", value = "状态", dataType = "Boolean", required = true)
    })
    @ValidateGroup(fields = {
            @ValidateField(index = 0, paramName = "编号", notNull = true, minLen = 4, maxLen = 10, regStr = "^[0-9a-zA-Z]{4,10}$", regErrorMsg = "编号只能由数字和字母组成"),
            @ValidateField(index = 1, paramName = "名字", notNull = true, maxLen = 15),
            @ValidateField(index = 2, paramName = "联系方式", notNull = true, regStr = RegularUtil.PHONE_REGEX, regErrorMsg = "联系方式格式错误"),
            @ValidateField(index = 3, paramName = "状态", notNull = true)
    })
    @Permission(code = "010102", content = "添加系统用户")
    public ResponseEntity<Boolean> addSystemUser(String code, String name, String phone, Boolean status) throws Exception {
        SystemUser systemUser = systemUserService.getSystemUserByCode(code);
        if (systemUser != null) {
            throw new HttpParamException("系统用户【" + code + "】已存在");
        }
        systemUser = new SystemUser();
        systemUser.setCode(code);
        systemUser.setName(name);
        systemUser.setPhone(phone);
        systemUser.setPassword(MD5Util.string2MD5(phone.substring(5, 11)));
        systemUser.setStatus(status);
        systemUser.setUpdateDate(new Date());
        systemUser.setCreateDate(new Date());
        systemUserService.save(systemUser);
        return ok(Boolean.TRUE);
    }

    /**
     * 编辑系统用户
     *
     * @param name
     * @param phone
     * @param status
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.POST, produces = "application/json;")
    @ApiOperation(value = "编辑系统用户", httpMethod = "POST", produces = "application/json;")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名字", dataType = "String", required = true),
            @ApiImplicitParam(name = "phone", value = "联系方式", dataType = "String", required = true),
            @ApiImplicitParam(name = "status", value = "状态", dataType = "Boolean", required = true),
            @ApiImplicitParam(name = "id", value = "系统用户ID", dataType = "Integer", required = true)
    })
    @ValidateGroup(fields = {
            @ValidateField(index = 0, paramName = "名字", notNull = true, maxLen = 15),
            @ValidateField(index = 1, paramName = "联系方式", notNull = true, regStr = RegularUtil.PHONE_REGEX, regErrorMsg = "联系方式格式错误"),
            @ValidateField(index = 2, paramName = "状态", notNull = true)
    })
    @Permission(code = "010103", content = "编辑系统用户")
    public ResponseEntity<Boolean> updateSystemUser(String name, String phone, Boolean status, @PathVariable Integer id) throws Exception {
        SystemUser systemUser = systemUserService.getById(id);
        if (systemUser == null) {
            throw new HttpParamException("系统用户不存在");
        }
        systemUser.setName(name);
        systemUser.setPhone(phone);
        systemUser.setStatus(status);
        systemUserService.updateById(systemUser);
        return ok(Boolean.TRUE);
    }

    /**
     * 分配角色
     * 规则：
     * 用户有角色
     * - roleId为空，取消角色
     * - roleId不为空，修改角色
     * <p>
     * 用户无角色
     * - roleId为空，不做处理
     * - roleId不为空，添加角色
     *
     * @param roleId
     * @param id
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/{id}/role", method = RequestMethod.POST, produces = "application/json;")
    @ApiOperation(value = "分配角色", httpMethod = "POST", produces = "application/json;")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "系统角色", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "id", value = "系统用户ID", dataType = "Integer", required = true)
    })
    @Permission(code = "010103", content = "分配角色")
    public ResponseEntity<Boolean> assignRole(Integer roleId, @PathVariable Integer id) throws Exception {
        SystemUserRole systemUserRole = systemUserRoleService.getSystemUserRole(id);
        if (systemUserRole == null) {
            if (roleId == null) {
                return ok(Boolean.TRUE);
            }
            systemUserRole = new SystemUserRole();
            systemUserRole.setSystemRoleId(roleId);
            systemUserRole.setSystemUserId(id);
            systemUserRole.setUpdateDate(new Date());
            systemUserRole.setCreateDate(new Date());
            systemUserRoleService.save(systemUserRole);
        } else {
            if (roleId == null) {
                systemUserRoleService.deleteById(systemUserRole.getId());
            } else {
                systemUserRoleService.updateById(systemUserRole);
            }
        }
        return ok(Boolean.TRUE);
    }

    /**
     * 修改密码
     *
     * @param password
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/password", method = RequestMethod.POST, produces = "application/json;")
    @ApiOperation(value = "修改密码", httpMethod = "POST", produces = "application/json;")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "新密码", dataType = "String", required = true)
    })
    @ValidateGroup(fields = {
            @ValidateField(index = 0, paramName = "新密码", notNull = true)
    })
    @Permission(code = "010103", content = "修改密码")
    public ResponseEntity<Boolean> updatePassword(String password, HttpSession session) throws Exception {
        SystemUser systemUser = (SystemUser) session.getAttribute("currentUser");
        if (systemUser == null) {
            throw new HttpParamException("系统用户不存在");
        }
        systemUser.setPassword(string2MD5(password));
        systemUserService.updateById(systemUser);
        return ok(Boolean.TRUE);
    }
}
